﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.IO;
using S5230WallpaperCreator.Properties;
using System.Diagnostics;
using System.Reflection;
using System.Drawing.Drawing2D;
using System.Threading;
using System.Globalization;

namespace S5230WallpaperCreator
{
    /// <summary>
    /// 
    /// </summary>
    public partial class MainForm : Form
    {
        readonly Size Mode1 = new Size(240, 400);
        readonly Size Mode2 = new Size(240, 320);

        /// <summary>
        /// Initializes a new instance of the <see cref="MainForm"/> class.
        /// </summary>
        public MainForm()
        {
            InitializeComponent();

            AssemblyName asmName = Assembly.GetExecutingAssembly().GetName();

            this.Text += string.Format(" ({0}.{1})", asmName.Version.Major, asmName.Version.Minor);

            // Restore Mode
            RefreshMode();

        }

        /// <summary>
        /// Sets the localization.
        /// </summary>
        /// <param name="culture">The culture.</param>
        private static void SetLocalization(CultureInfo culture)
        {
            Thread.CurrentThread.CurrentUICulture = culture;

            foreach (Form form in Application.OpenForms)
            {
                ApplyControlResources(new ComponentResourceManager(form.GetType()), form);
            }
        }

        /// <summary>
        /// Applies the control resources.
        /// </summary>
        /// <param name="resourceManager">The resource manager.</param>
        /// <param name="control">The control.</param>
        private static void ApplyControlResources(ComponentResourceManager resourceManager, Control control)
        {
            if (control is Form)
                resourceManager.ApplyResources(control, "$this");
            else
                resourceManager.ApplyResources(control, control.Name);

            if (control is IContainerControl)
            {
                foreach (Control childControl in control.Controls)
                {
                    ApplyControlResources(resourceManager, childControl);
                }
            }

            if (control is ToolStrip)
            {
                foreach (ToolStripItem childControl in ((ToolStrip)control).Items)
                {
                    resourceManager.ApplyResources(childControl, childControl.Name);
                }
            }
        }


        /// <summary>
        /// Processes a command key.
        /// </summary>
        /// <param name="msg">A <see cref="T:System.Windows.Forms.Message"/>, passed by reference, that represents the Win32 message to process.</param>
        /// <param name="keyData">One of the <see cref="T:System.Windows.Forms.Keys"/> values that represents the key to process.</param>
        /// <returns>
        /// true if the keystroke was processed and consumed by the control; otherwise, false to allow further processing.
        /// </returns>
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            switch (keyData)
            {
                case Keys.Control | Keys.S:
                    OnSaveWallpaper();
                    return true;
                case Keys.Control | Keys.O:
                    OnOpenWallpaper();
                    return true;
                case Keys.Control | Keys.D1:
                    this.wallpaperViewUserControl.SelectLeftImage();
                    return true;
                case Keys.Control | Keys.D2:
                    this.wallpaperViewUserControl.SelectCenterImage();
                    return true;
                case Keys.Control | Keys.D3:
                    this.wallpaperViewUserControl.SelectRightImage();
                    return true;
            }

            return base.ProcessCmdKey(ref msg, keyData);
        }

        /// <summary>
        /// Refreshes the mode.
        /// </summary>
        private void RefreshMode()
        {
            // Update Mode Menu
            int currentMode = Settings.Default.Mode;
            if (currentMode > toolStripDropDownButtonSize.DropDownItems.Count - 2)
                currentMode = 0;

            if (currentMode >= 0)
            {
                for (int index = 0; index < toolStripDropDownButtonSize.DropDownItems.Count - 2; index++)
                {
                    ((ToolStripMenuItem)toolStripDropDownButtonSize.DropDownItems[index]).Checked = (currentMode == index);

                    if (currentMode == index)
                    {
                        toolStripDropDownButtonSize.Text = toolStripDropDownButtonSize.DropDownItems[index].Text;
                    }
                }
            }
            else
            {
                // Custom Mode
                toolStripDropDownButtonSize.Text = string.Format(Resources.CustomMode_Text, Settings.Default.CustomModeWidth, Settings.Default.CustomModeHeight);

                for (int index = 0; index < toolStripDropDownButtonSize.DropDownItems.Count - 2; index++)
                {
                    ((ToolStripMenuItem)toolStripDropDownButtonSize.DropDownItems[index]).Checked = false;
                }

                ((ToolStripMenuItem)toolStripDropDownButtonSize.DropDownItems[toolStripDropDownButtonSize.DropDownItems.Count - 1]).Checked = true;
            }

            SetImageSizeByMode();
        }


        /// <summary>
        /// Handles the Click event of the buttonCreate control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void buttonCreate_Click(object sender, EventArgs e)
        {
            OnSaveWallpaper();
        }

        /// <summary>
        /// Called when [save wallpaper].
        /// </summary>
        private void OnSaveWallpaper()
        {
            if (Directory.Exists(Settings.Default.MainDialog_SourceImageFolder))
                saveFileDialog.InitialDirectory = Settings.Default.MainDialog_OutputImageFolder;

            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                using (Bitmap image = new Bitmap(wallpaperViewUserControl.ImageSize.Width * 3, wallpaperViewUserControl.ImageSize.Height))
                {
                    using (Graphics gr = Graphics.FromImage(image))
                    {
                        SetHighQuality(gr);

                        gr.DrawImage(this.wallpaperViewUserControl.LeftImage, 0, 0, wallpaperViewUserControl.ImageSize.Width, wallpaperViewUserControl.ImageSize.Height);
                        gr.DrawImage(this.wallpaperViewUserControl.CenterImage, wallpaperViewUserControl.ImageSize.Width, 0, wallpaperViewUserControl.ImageSize.Width, wallpaperViewUserControl.ImageSize.Height);
                        gr.DrawImage(this.wallpaperViewUserControl.RightImage, wallpaperViewUserControl.ImageSize.Width * 2, 0, wallpaperViewUserControl.ImageSize.Width, wallpaperViewUserControl.ImageSize.Height);

                        if (saveFileDialog.FileName.EndsWith(".bmp", StringComparison.OrdinalIgnoreCase))
                        {
                            image.Save(saveFileDialog.FileName, ImageFormat.Bmp);
                        }
                        else
                        {
                            System.Drawing.Imaging.ImageCodecInfo[] Info = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
                            System.Drawing.Imaging.EncoderParameters Params = new System.Drawing.Imaging.EncoderParameters(1);
                            Params.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);

                            image.Save(saveFileDialog.FileName, Info[1], Params);
                        }
                    }
                }

                Settings.Default.MainDialog_OutputImageFolder = Path.GetDirectoryName(saveFileDialog.FileName);
                Settings.Default.Save();
            }
        }

        /// <summary>
        /// Sets the high quality.
        /// </summary>
        /// <param name="gr">The gr.</param>
        private static void SetHighQuality(Graphics gr)
        {
            gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
            gr.SmoothingMode = SmoothingMode.HighQuality;
            gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
            gr.CompositingQuality = CompositingQuality.HighQuality;
        }

        /// <summary>
        /// Handles the Click event of the buttonSwitcherLC control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void buttonSwitcherLC_Click(object sender, EventArgs e)
        {
            this.wallpaperViewUserControl.SwitchLeftCenterImages();
        }

          /// <summary>
        /// Handles the Click event of the buttonSwitcherCR control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void buttonSwitcherCR_Click(object sender, EventArgs e)
        {
            this.wallpaperViewUserControl.SwitchCenterRightImages();
        }

          /// <summary>
        /// Handles the FormClosing event of the MainForm control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Forms.FormClosingEventArgs"/> instance containing the event data.</param>
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
        }

        /// <summary>
        /// Handles the LinkClicked event of the linkLabelGoToHomePage control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Forms.LinkLabelLinkClickedEventArgs"/> instance containing the event data.</param>
        private void linkLabelGoToHomePage_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            Help.ShowHelp(this, "http://code.google.com/p/s5230wallpapercreator/");
        }


        /// <summary>
        /// Opens the S5600 wallpaper.
        /// </summary>
        /// <param name="wallpaper">The wallpaper.</param>
        private void OpenWallpaper(Image wallpaper)
        {
            Size imageSize = wallpaperViewUserControl.ImageSize;

            if (wallpaper == null)
                throw new ArgumentNullException("wallpaper");

            if (wallpaper.Size.Width != imageSize.Width * 3 || wallpaper.Size.Height != imageSize.Height)
                throw new Exception(string.Format(Resources.Error_WrongWallpaperSize,
                    imageSize.Width * 3, imageSize.Height));

            OnNewWallpaper(imageSize);

            Bitmap leftImage = new Bitmap(imageSize.Width, imageSize.Height);
            Bitmap centerImage = new Bitmap(imageSize.Width, imageSize.Height);
            Bitmap rightImage = new Bitmap(imageSize.Width, imageSize.Height);

            using (Graphics gr = Graphics.FromImage(leftImage))
            {
                SetHighQuality(gr);

                gr.DrawImage(wallpaper, 0, 0, new Rectangle(0, 0, imageSize.Width, imageSize.Height), GraphicsUnit.Pixel);
            }
            using (Graphics gr = Graphics.FromImage(centerImage))
            {
                SetHighQuality(gr);

                gr.DrawImage(wallpaper, 0, 0, new Rectangle(imageSize.Width, 0, imageSize.Width, imageSize.Height), GraphicsUnit.Pixel);
            }
            using (Graphics gr = Graphics.FromImage(rightImage))
            {
                SetHighQuality(gr);

                gr.DrawImage(wallpaper, 0, 0, new Rectangle(imageSize.Width * 2, 0, imageSize.Width, imageSize.Height), GraphicsUnit.Pixel);
            }

            this.wallpaperViewUserControl.LeftImage = leftImage;
            this.wallpaperViewUserControl.CenterImage = centerImage;
            this.wallpaperViewUserControl.RightImage = rightImage;
        }

        /// <summary>
        /// Called when [open wallpaper].
        /// </summary>
        private void OnOpenWallpaper()
        {
            if (Directory.Exists(Settings.Default.MainDialog_SourceImageFolder))
                openWallpaperFileDialog.InitialDirectory = Settings.Default.MainDialog_OutputImageFolder;

            if (openWallpaperFileDialog.ShowDialog() == DialogResult.OK)
            {
                // TODO: Resolve By Mode
                try
                {
                    Image wallpaperImage = Image.FromFile(openWallpaperFileDialog.FileName);

                    OpenWallpaper(wallpaperImage);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(this,
                    string.Format(Resources.Error_CanNotOpenImage, openWallpaperFileDialog.FileName, ex.Message),
                    Resources.Error_OpenImage_Caption,
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                Settings.Default.MainDialog_OutputImageFolder = Path.GetDirectoryName(openWallpaperFileDialog.FileName);
                Settings.Default.Save();
            }
        }


        /// <summary>
        /// Called when [new wallpaper].
        /// </summary>
        /// <param name="imageSize">Size of the image.</param>
        private void OnNewWallpaper(Size imageSize)
        {
            this.wallpaperViewUserControl.ResetAllImages();
            this.wallpaperViewUserControl.ImageSize = imageSize;
        }

        /// <summary>
        /// Handles the Click event of the toolStripButtonSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void toolStripButtonSave_Click(object sender, EventArgs e)
        {
            OnSaveWallpaper();
        }

        /// <summary>
        /// Handles the Click event of the toolStripSplitButtonOpen control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void toolStripSplitButtonOpen_Click(object sender, EventArgs e)
        {
            //SetLocalization(new System.Globalization.CultureInfo("ru"));

            OnOpenWallpaper();
        }

        /// <summary>
        /// Handles the DropDownOpening event of the toolStripDropDownButtonSize control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void toolStripDropDownButtonSize_DropDownOpening(object sender, EventArgs e)
        {
        }

        /// <summary>
        /// Handles the DropDownItemClicked event of the toolStripDropDownButtonSize control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Forms.ToolStripItemClickedEventArgs"/> instance containing the event data.</param>
        private void toolStripDropDownButtonSize_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            int index  = toolStripDropDownButtonSize.DropDownItems.IndexOf(e.ClickedItem);

            if(index == toolStripDropDownButtonSize.DropDownItems.Count - 1)
            {
                CustomModeForm form = new CustomModeForm();

                form.SetSize(new Size(Settings.Default.CustomModeWidth, Settings.Default.CustomModeHeight));

                if (form.ShowDialog() == DialogResult.OK)
                {
                    Size size = form.GetSize();

                    Settings.Default.Mode = -1;
                    Settings.Default.CustomModeWidth = size.Width;
                    Settings.Default.CustomModeHeight = size.Height;

                    Settings.Default.Save();

                    RefreshMode();
                }
            }
            else
            {
                Settings.Default.Mode = index;
                Settings.Default.Save();

                RefreshMode();
            }
        }

        /// <summary>
        /// Sets the image size by mode.
        /// </summary>
        private void SetImageSizeByMode()
        {
            switch (Settings.Default.Mode)
            {
                case -1:
                    OnNewWallpaper(new Size(Settings.Default.CustomModeWidth, Settings.Default.CustomModeHeight));
                    break;
                case 1:
                    OnNewWallpaper(Mode2);
                    break; 
                case 0:
                default:
                    OnNewWallpaper(Mode1);
                    break;
            }
        }
    }
}

